home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / look / source / tiff.c < prev    next >
Text File  |  1991-10-18  |  17KB  |  708 lines

  1. /****************************************************
  2.  
  3.     TIFF Graphic Data File Display Window Program
  4.  
  5. *****************************************************/
  6. #include    <stdio.h>
  7. #include    <stdlib.h>
  8. #include    <egb.h>
  9. #include    <mos.h>
  10.  
  11. #define PAGE0   0
  12. #define    PAGE1    0x040000
  13.  
  14. #define SHORT   short int
  15. #define UCHAR   unsigned char
  16.  
  17. #define    WLX        wfp->wd_lx
  18. #define    WLY        wfp->wd_ly
  19. #define    WRX        wfp->wd_rx
  20. #define    WRY        wfp->wd_ry
  21. #define    WFRA    wfp->wd_fra
  22. #define    WBAK    wfp->wd_bak
  23.  
  24. typedef struct wdtmp {
  25.     SHORT    wd_mode;
  26.     SHORT    wd_lx, wd_ly;
  27.     SHORT    wd_rx, wd_ry;
  28.     char    *wd_img;
  29.     struct    wdtmp *wd_forwfp;
  30.     struct    wdtmp *wd_nxtwfp;
  31.  
  32.     SHORT    wd_fntsiz;
  33.     SHORT    wd_x, wd_y;        /* グラフィック座標 */
  34.     SHORT    wd_len;
  35.     char    wd_buf[256];
  36.     SHORT    wd_dx, wd_dy;    /* グラフィック・表示座標 */
  37.     SHORT    wd_cx, wd_cy;    /* コンソ-ル座標 */
  38.     SHORT    wd_mx, wd_my;    /* コンソ-ル・サイズ */
  39.     SHORT    wd_tab;
  40.     SHORT    wd_offx;
  41.  
  42.     SHORT    wd_fra, wd_bak, wd_chr;
  43.  
  44.     SHORT    wd_valsiz;
  45.     SHORT    wd_valtop;
  46.     int        wd_entsiz;
  47.     int        wd_bufsiz;
  48.     char    *wd_bftop;
  49.     char    *wd_bfbtm;
  50.     char    *wd_dptop;
  51.     UCHAR    *wd_dpptr;
  52.     SHORT    wd_dpflg;
  53.  
  54.     char    wd_ttl[80];
  55. } WINDFP;
  56.  
  57. typedef struct {
  58.     int        im_page;            /* 0x00000 or 0x40000 */
  59.     int        im_off;                /* Disp Offset */
  60.     int        im_x, im_y;            /* Display Point */
  61.     int        im_sx,im_sy;        /* Display Size */
  62.     char    *im_adr;            /* img address */
  63.     int        im_ix,im_iy;        /* img Display Point */
  64.     int        im_isx,im_isy;        /* img size */
  65. } IMG_PARA;
  66.  
  67. typedef struct {
  68.     SHORT    tf_tag;
  69.     SHORT    tf_type;
  70.     int        tf_len;
  71.     int        tf_data;
  72. } TIF_IFD;
  73.  
  74. extern void        IMG_move(IMG_PARA *para);
  75. extern WINDFP    *WIN_dmyopen(int x1,int y1,int x2,int y2);
  76. extern char        *subname(char *nam);
  77.  
  78. void    TIF_disp(register WINDFP *wfp)
  79. {
  80.     IMG_PARA para;
  81.  
  82.     para.im_off = para.im_page = 0;
  83.     para.im_x = wfp->wd_dx; para.im_y = wfp->wd_dy;
  84.     para.im_sx = (wfp->wd_mx < (wfp->wd_x - wfp->wd_cx) ? wfp->wd_mx : 
  85.                                (wfp->wd_x - wfp->wd_cx)); 
  86.     para.im_sy = (wfp->wd_my < (wfp->wd_y - wfp->wd_cy) ? wfp->wd_my : 
  87.                                (wfp->wd_y - wfp->wd_cy)); 
  88.     para.im_adr = wfp->wd_bftop;
  89.     para.im_ix = wfp->wd_cx; para.im_iy = wfp->wd_cy;
  90.     para.im_isx = wfp->wd_x; para.im_isy = wfp->wd_y;
  91.     IMG_move(¶);
  92. }
  93. void    TIF_seek(register WINDFP *wfp)
  94. {
  95.     int        b,x,y,sx=0,sy=0;
  96.  
  97.     MOS_rdpos(&b,&x,&y);
  98.     wrtmos(2);
  99.     MOS_horizon(WRX-18,WRX-8);
  100.     MOS_vertical(WLY + 20,WRY - 32);
  101.     do {
  102.         MOS_rdpos(&b,&x,&y);
  103.         if ( x >= (WRX - 18) && x <= WRX ) {
  104.             if ( y >= (WLY + 20) && y <= (WLY + 36) ) {
  105.                 if ( (wfp->wd_cy -= 8) < 0 )
  106.                     wfp->wd_cy = 0;
  107.                 TIF_disp(wfp);
  108.             } else if ( y >= (WRY - 38) && y <= (WRY - 20) ) {
  109.                 if ( (wfp->wd_cy + wfp->wd_my + 8) <= wfp->wd_y ) {
  110.                     wfp->wd_cy += 8;
  111.                     TIF_disp(wfp);
  112.                 }
  113.             }
  114.         }
  115.     } while ( (b & 1) != 0 );
  116.     MOS_horizon(0,1023);
  117.     MOS_vertical(0,511);
  118.     wrtmos(0);
  119. }
  120. void    TIF_xseek(register WINDFP *wfp)
  121. {
  122.     int        b,x,y,sx=0,sy=0;
  123.  
  124.     wrtmos(2);
  125.     MOS_horizon(WLX,WRX-28);
  126.     MOS_vertical(WRY-18,WRY-2);
  127.     do {
  128.         MOS_rdpos(&b,&x,&y);
  129.         if ( x < (WLX + 18) && y >= (WRY - 18) ) {
  130.             if ( wfp->wd_cx > 0 ) {
  131.                 wfp->wd_cx -= 8;
  132.                 TIF_disp(wfp);
  133.             }
  134.         } else if ( x >= (WRX - 36) && x < (WRX - 20) && 
  135.                     y >= (WRY - 18) ) {
  136.             if ( (wfp->wd_cx + wfp->wd_mx + 8) <= wfp->wd_x ) {
  137.                 wfp->wd_cx += 8;
  138.                 TIF_disp(wfp);
  139.             }
  140.         }
  141.     } while ( (b & 1) != 0 );
  142.     MOS_horizon(0,1023);
  143.     MOS_vertical(0,511);
  144.     wrtmos(0);
  145. }
  146. void    TIF_move(register WINDFP *wfp)
  147. {
  148.     wfp->wd_mode = 0x0003;
  149.     WIN_move(wfp);
  150.     wfp->wd_dx = WLX + 4; wfp->wd_dy = WLY + 24;
  151. }
  152. void    TIF_size(register WINDFP *wfp)
  153. {
  154.     wfp->wd_mode = 0x0003;
  155.     WIN_size(wfp);
  156.     wfp->wd_dx = WLX + 4; wfp->wd_dy = WLY + 24;
  157.     if ( (wfp->wd_mx = (WRX - 22) - (WLX + 4)) > wfp->wd_x )
  158.         wfp->wd_mx = wfp->wd_x; 
  159.     if ( (wfp->wd_my = (WRY - 20) - (WLY + 24)) > wfp->wd_y )
  160.         wfp->wd_my = wfp->wd_y;
  161.     wfp->wd_cx = wfp->wd_cy = 0;
  162.     TIF_disp(wfp);
  163. }
  164. void    TIF_subcom(WINDFP *wfp)
  165. {
  166.     char    tmp[80];
  167.  
  168.     sprintf(tmp,"%dBit %dx%d Graphic Data....",(int)wfp->wd_len,
  169.                                            (int)wfp->wd_x,(int)wfp->wd_y);
  170.     MSG_disp(tmp,13);
  171. }
  172. void    TIF_select(register WINDFP *wfp)
  173. {
  174.     int        b,x,y;
  175.  
  176.     MOS_rdpos(&b,&x,&y);
  177.     if ( x <= (WLX + 16) && y <= (WLY + 16) )
  178.         WIN_close(wfp);
  179.     else if ( x >= (WRX - 16) && y >= (WRY - 16) )
  180.         TIF_size(wfp);
  181.     else if ( x >= (WRX - 16) && y <= (WLY + 16) )
  182.         TIF_subcom(wfp); 
  183.     else if ( x >= (WRX - 18) )
  184.         TIF_seek(wfp);
  185.     else if ( y <= (WLY + 20) )
  186.         TIF_move(wfp);
  187.     else if ( x < (WRX - 16) && y >= (WRY - 20) )
  188.         TIF_xseek(wfp);
  189. }
  190. void    TIF_get1(WINDFP *wfp,FILE *fp)
  191. {
  192.     int        x,y,sx,sy,ex,sz;
  193.     int        mk,bf,ch;
  194.     char    *p;
  195.  
  196.     sx = wfp->wd_x; sy = wfp->wd_y;
  197.     wfp->wd_x = ex = (sx + 1) & 0xfffe;
  198.     sz = sy * ex / 2;
  199.     if ( (wfp->wd_bftop = p = malloc(sz)) == NULL )
  200.         return;
  201.     memset(p,0x88,sz);
  202.     for ( mk = y = 0 ; y < sy ; y++ ) {
  203.         for ( x = 0 ; x < sx ; x++ ) {
  204.             if ( (mk >>= 1) == 0 ) { bf = getc(fp); mk = 0x80; }
  205.             if ( (bf & mk) == 0 ) ch = 0x08; else ch = 0x0f;
  206.             if ( (x & 1) == 0 ) *p = ch; else *(p++) |= (ch << 4);
  207.         }
  208.         if ( ex != sx )
  209.             *(p++) |= 0x80;
  210.         if ( (y & 15) == 15 ) {
  211.             if ( y > wfp->wd_my ) wfp->wd_cy = y - wfp->wd_my;
  212.             TIF_disp(wfp);
  213.         }
  214.     }
  215. }
  216. void    TIF_get4(WINDFP *wfp,FILE *fp)
  217. {
  218.     int        i,x,y,sx,sy,ex,sz;
  219.     char    *p;
  220.  
  221.     sx = wfp->wd_x; sy = wfp->wd_y;
  222.     wfp->wd_x = ex = (sx + 1) & 0xfffe;
  223.     sz = sy * ex / 2;
  224.     if ( (wfp->wd_bftop = p = malloc(sz)) == NULL )
  225.         return;
  226.     fread(p,1,sz,fp);
  227.     if ( sx != ex ) {
  228.         i = ex / 2;
  229.         for ( y = 0 ; y < sy ; y++ ) {
  230.             *(p+i-1) |= 0x80;
  231.             p += i;
  232.         }
  233.     }
  234. }
  235. /***************************************************************
  236. void    TIF_get8(WINDFP *wfp,FILE *fp)
  237. {
  238.     int        b,r,g;
  239.     int        j,i,n;
  240.     int        x,y,sx,sy,ex,sz;
  241.     char    *p;
  242.     unsigned char *dm,*dp,*s;
  243.     static SHORT ptn[]={ 0x0000,0x0f00,0x00f0,0x0ff0,
  244.                          0xf00f,0xff0f,0xf0ff,0xffff };
  245.  
  246.     sx = wfp->wd_x;
  247.     wfp->wd_x &= 0xfffe; wfp->wd_y &= 0xfffe;
  248.     ex = wfp->wd_x; sy = wfp->wd_y;
  249.     sz = sy * ex / 2;
  250.     if ( (wfp->wd_bftop = p = malloc(sz)) == NULL )
  251.         return;
  252.     if ( (dm = malloc(sx*2)) == NULL ) {
  253.         free(p); wfp->wd_bftop = NULL;
  254.         return;
  255.     }
  256.     memset(p,0x88,sz);
  257.     if ( wfp->wd_tab != 0 )
  258.         s = wfp->wd_dpptr;
  259.     else {
  260.         if ( (s = malloc(768)) == NULL ) {
  261.             free(dm); free(p); wfp->wd_bftop = NULL;
  262.             return;
  263.         }
  264.         for ( j = i = 0 ; i < 256 ; i++,j+=3 ) {
  265.             s[i * 3] = j;
  266.             s[i * 3 + 1] = j;
  267.             s[i * 3 + 2] = j;
  268.         }
  269.     }
  270.     for ( y = 0 ; y < sy ; y+=2 ) {
  271.         fread(dm,1,sx * 2,fp);
  272.         for ( dp = dm,x = 0 ; x < sx ; x+=2,p++,dp+=2 ) {
  273.             b = s[*dp * 3] >> 4;
  274.             r = s[*dp * 3 + 1] >> 4;
  275.             g = s[*dp * 3 + 2] >> 4;
  276.             b = ptn[b & 7] & (b > 7 ? 0x9999 : 0x1111);
  277.             r = ptn[r & 7] & (r > 7 ? 0xAAAA : 0x2222);
  278.             g = ptn[g & 7] & (g > 7 ? 0xCCCC : 0x4444);
  279.             i = b | r | g;
  280.             *p = i >> 8; *(p + (ex / 2)) = i & 0xff;
  281.         }
  282.         p += (ex / 2);
  283.         if ( (y & 15) == 14 ) {
  284.             if ( y > wfp->wd_my ) wfp->wd_cy = y - wfp->wd_my;
  285.             TIF_disp(wfp);
  286.         }
  287.     }
  288.     free(s);
  289.     free(dm);
  290. }
  291. ********************************************************************/
  292. void    TIF_get8(WINDFP *wfp,FILE *fp)
  293. {
  294.     int        b,r,g;
  295.     int        j,i,n;
  296.     int        x,y,sx,sy,ex,sz;
  297.     char    *p;
  298.     unsigned char *dm,*dp,*s;
  299.     static char bit[]={ 1,1,1,2,1,2,2,3 };
  300.  
  301.     sx = wfp->wd_x; sy = wfp->wd_y;
  302.     wfp->wd_x = ex = (sx + 1) & 0xfffe;
  303.     sz = sy * ex / 2;
  304.     if ( (wfp->wd_bftop = p = malloc(sz+1)) == NULL )
  305.         return;
  306.     if ( (dm = malloc(sx)) == NULL ) {
  307.         free(p); wfp->wd_bftop = NULL;
  308.         return;
  309.     }
  310.     memset(p,0x88,sz);
  311.     s = wfp->wd_dpptr;
  312.     for ( y = 0 ; y < sy ; y++ ) {
  313.         fread(dm,1,sx,fp);
  314.         if ( wfp->wd_tab != 0 ) {
  315.             for ( dp = dm,x = 0 ; x < sx ; x++ ) {
  316.                 i = *(dp++); j = 0;
  317.                 b = s[i*3]; r = s[i*3+1]; g = s[i*3+2]; i = 0;
  318.                 if ( (n = b + r + g) == 0 ) n = 1;
  319.                 if ( (b * 100 / n) > 30 ) { j |= 0x01; i += b; }
  320.                 if ( (r * 100 / n) > 30 ) { j |= 0x02; i += r; }
  321.                 if ( (g * 100 / n) > 30 ) { j |= 0x04; i += g; }
  322.                 if ( (i / bit[j]) > 150 ) j |= 0x08;
  323.  
  324.                 if ( (x & 1) == 0 ) 
  325.                     *p = j;
  326.                 else 
  327.                     *(p++) |= (j << 4);
  328.             }
  329.         } else {
  330.             for ( dp = dm,x = 0 ; x < sx ; x++ ) {
  331.                 i = *(dp++); j = 0;
  332.                 if ( (i & 0x03) != 0 ) j |= 0x01;
  333.                 if ( (i & 0x1C) != 0 ) j |= 0x02;
  334.                 if ( (i & 0xE0) != 0 ) j |= 0x04; 
  335.                 if ( (i & 0x92) != 0 ) j |= 0x08;
  336.                 if ( (x & 1) == 0 ) 
  337.                     *p = j;
  338.                 else 
  339.                     *(p++) |= (j << 4);
  340.             }
  341.         }
  342.         if ( ex != sx )
  343.             *(p++) |= 0x80;
  344.         if ( (y & 15) == 15 ) {
  345.             if ( y > wfp->wd_my ) wfp->wd_cy = y - wfp->wd_my;
  346.             TIF_disp(wfp);
  347.         }
  348.     }
  349.     free(dm);
  350.     if ( wfp->wd_tab != 0 )
  351.         free(wfp->wd_dpptr);
  352. }
  353. void    TIF_get16(WINDFP *wfp,FILE *fp)
  354. {
  355.     int     i,b,r,g;
  356.     int     x,y,sx,sy,ex,sz;
  357.     char    *p;
  358.     static SHORT ptn[]={ 0x0000,0x0f00,0x00f0,0x0ff0,
  359.                          0xf00f,0xff0f,0xf0ff,0xffff };
  360.  
  361.     sx = wfp->wd_x; sy = wfp->wd_y;
  362.     wfp->wd_x *= 2; wfp->wd_y *= 2;
  363.     ex = (sx + 1) & 0xfffe;
  364.     sz = sy * sx * 2;
  365.     if ( (wfp->wd_bftop = p = malloc(sz)) == NULL )
  366.         return;
  367.     memset(p,0x88,sz);
  368.     for ( y = 0 ; y < sy ; y++,p += sx ) {
  369.         for ( x = 0 ; x < sx ; x++,p++ ) {
  370.             fread(&i,2,1,fp);
  371.             b = (i >> 1) & 15; b = ptn[b & 7] & (b > 7 ? 0x9999 : 0x1111);
  372.             r = (i >> 6) & 15; r = ptn[r & 7] & (r > 7 ? 0xAAAA : 0x2222);
  373.             g = (i >> 11) & 15;g = ptn[g & 7] & (g > 7 ? 0xCCCC : 0x4444);
  374.             i = b | r | g;
  375.             *p = i >> 8; *(p + sx) = i & 0xff;
  376.         }
  377.         if ( (y & 7) == 7 ) {
  378.             if ( (y * 2) > wfp->wd_my ) wfp->wd_cy = (y * 2) - wfp->wd_my;
  379.             TIF_disp(wfp);
  380.         }
  381.     }
  382. }
  383. int        swap(char *p)
  384. {
  385.     int        i;
  386.     char    *s;
  387.  
  388.     s = (char *)&i;
  389.     p += 4;
  390.     *(s++) = *(--p); 
  391.     *(s++) = *(--p); 
  392.     *(s++) = *(--p); 
  393.     *(s++) = *(--p); 
  394.     return i;
  395. }
  396. void    TIF_open(WINDFP *wfp,FILE *fp)
  397. {
  398.     int        i,l;
  399.     TIF_IFD    ifd;
  400.     char    tmp[8];
  401.  
  402.     if ( fread(tmp,1,4,fp) < 4 )
  403.         return;
  404.     if ( tmp[0] != 0x49 || tmp[1] != 0x49 || tmp[2] != 0x2A )
  405.         return;
  406.     if ( fread(&l,4,1,fp) < 1 )
  407.         return;
  408.     fseek(fp,l,0); i = 0;
  409.     if ( fread(&i,2,1,fp) < 1 )
  410.         return;
  411.     while ( i-- > 0) {
  412.         if ( fread(&ifd,sizeof(TIF_IFD),1,fp) < 1 )
  413.             return;
  414.         if ( ifd.tf_tag == 0 ) break;
  415.         switch(ifd.tf_tag){
  416.             case 0x0100: wfp->wd_x = ifd.tf_data; break;
  417.             case 0x0101: wfp->wd_y = ifd.tf_data; break;
  418.             case 0x0102: wfp->wd_len = ifd.tf_data; break;
  419.             case 0x0111: l = ifd.tf_data; break;
  420.         }
  421.     }
  422.     fseek(fp,l,0);
  423. }
  424. void    PIC_open(WINDFP *wfp,FILE *fp)
  425. {
  426.     wfp->wd_x = 320; wfp->wd_y = 240;
  427.     wfp->wd_len = 16;
  428. }
  429. void    GRP_open(WINDFP *wfp,FILE *fp)
  430. {
  431.     long        l;
  432.     char    tmp[8];
  433.  
  434.     if ( fread(tmp,1,4,fp) < 4 )
  435.         return;
  436.     if ( fread(tmp,1,4,fp) < 4 )
  437.         return;
  438.     wfp->wd_x = swap(tmp);
  439.     if ( fread(tmp,1,4,fp) < 4 )
  440.         return;
  441.     wfp->wd_y = swap(tmp);
  442.     if ( fread(tmp,1,4,fp) < 4 )
  443.         return;
  444.     if ( (wfp->wd_len = swap(tmp)) == 15 )
  445.         wfp->wd_len = 16;
  446.     switch(wfp->wd_len) {
  447.         case 4: l = 0x0050l; break;
  448.         case 8:
  449.             fseek(fp,0x0020l,0);
  450.             if ( (wfp->wd_dpptr = malloc(768)) != NULL ) {
  451.                 wfp->wd_tab = 1;
  452.                 fread(wfp->wd_dpptr,1,768,fp);
  453.             }
  454.             l = 0x0320l; 
  455.             break;
  456.         case 16: l = 0x0020l; break;
  457.     }
  458.     fseek(fp,l,0);
  459. }
  460. void    GED_open(WINDFP *wfp,FILE *fp)
  461. {
  462.     SHORT    i;
  463.  
  464.     fseek(fp,0x000Cl,0);
  465.     if ( fread(&i,2,1,fp) < 1 )
  466.         return;
  467.     wfp->wd_x = i + 1;
  468.     if ( fread(&i,2,1,fp) < 1 )
  469.         return;
  470.     wfp->wd_y = i + 1;
  471.     wfp->wd_len = 16;
  472.     fseek(fp,0x0100l,0);
  473. }
  474. void    FIG_open(WINDFP *wfp,FILE *fp)
  475. {
  476.     SHORT    i;
  477.  
  478.     fseek(fp,0x000Cl,0);
  479.     if ( fread(&i,2,1,fp) < 1 )
  480.         return;
  481.     wfp->wd_x = i + 1;
  482.     if ( fread(&i,2,1,fp) < 1 )
  483.         return;
  484.     wfp->wd_y = i + 1;
  485.     wfp->wd_len = 16;
  486.     fseek(fp,0x0100l,0);
  487. }
  488. void    P16_open(WINDFP *wfp,FILE *fp)
  489. {
  490.     SHORT    i;
  491.  
  492.     fseek(fp,0x0082l,0);
  493.     if ( fread(&i,2,1,fp) < 1 )
  494.         return;
  495.     wfp->wd_x = i + 1;
  496.     if ( fread(&i,2,1,fp) < 1 )
  497.         return;
  498.     wfp->wd_y = i + 1;
  499.     wfp->wd_len = 4;
  500.     fseek(fp,0x0086l,0);
  501. }
  502. void    P25_open(WINDFP *wfp,FILE *fp)
  503. {
  504.     SHORT    i;
  505.  
  506.     fseek(fp,0x0622l,0);
  507.     if ( fread(&i,2,1,fp) < 1 )
  508.         return;
  509.     wfp->wd_x = i + 1;
  510.     if ( fread(&i,2,1,fp) < 1 )
  511.         return;
  512.     wfp->wd_y = i + 1;
  513.     wfp->wd_len = 16;
  514.     fseek(fp,0x0626l,0);
  515. }
  516. void    P32_open(WINDFP *wfp,FILE *fp)
  517. {
  518.     SHORT    i;
  519.  
  520.     fseek(fp,0x01E2l,0);
  521.     if ( fread(&i,2,1,fp) < 1 )
  522.         return;
  523.     wfp->wd_x = i + 1;
  524.     if ( fread(&i,2,1,fp) < 1 )
  525.         return;
  526.     wfp->wd_y = i + 1;
  527.     wfp->wd_len = 16;
  528.     fseek(fp,0x01E6l,0);
  529. }
  530. int        GIF_pix(int pix,int gcf,char *gctb,FILE *fp)
  531. {
  532.     static char bit[]={ 1,1,1,2,1,2,2,3 };
  533.     int        i,j,n,r,g,b;
  534.  
  535.     if ( (n = dmy_getc(fp)) == EOF )
  536.         return EOF;
  537.  
  538.     if ( gcf != 0 ) {
  539.         r = gctb[n * 3]; g = gctb[n * 3 + 1]; b = gctb[n * 3 + 2];
  540.         j = i =0;
  541.         if ( (n = b + r + g) == 0 ) n = 1;
  542.         if ( (b * 100 / n) > 30 ) { j |= 0x01; i += b; }
  543.         if ( (r * 100 / n) > 30 ) { j |= 0x02; i += r; }
  544.         if ( (g * 100 / n) > 30 ) { j |= 0x04; i += g; }
  545.         if ( (i / bit[j]) > 150 ) j |= 0x08;
  546.     } else {
  547.         if ( pix == 4 ) j = n;
  548.         else if ( pix > 4 ) j = n >> (pix - 4);
  549.         else j = n;
  550.     }
  551.     return j;
  552. }
  553. void    GIF_open(WINDFP *wfp,FILE *fp)
  554. {
  555.     int        i,j,n,x,y;
  556.     int        pix,gcf,sku,sz;
  557.     SHORT    si,dx,dy,mx,my,ex;
  558.     char    *p,*gctb;
  559.     char    tmp[16];
  560.     static SHORT skutb[4]={ 8,8,4,2 };
  561.     static SHORT skusp[4]={ 0,4,2,1 };
  562.  
  563.     fread(tmp,1,6,fp);
  564.     if ( strncmp(tmp,"GIF87a",6) != 0 )
  565.         return;
  566.  
  567.     fread(&si,2,1,fp);
  568.     wfp->wd_x = ex = (si + 1) & 0xfffe;
  569.     fread(&si,2,1,fp);
  570.     wfp->wd_y = si;
  571.     sz = si * ex / 2;
  572.     if ( (wfp->wd_bftop = p = malloc(sz)) == NULL )
  573.         goto ERROR;
  574.     memset(p,0x88,sz);
  575.  
  576.     fread(tmp,1,3,fp);
  577.     pix = (tmp[0] & 7) + 1; wfp->wd_len = pix + 100;
  578.     if ( (gcf = tmp[0] & 0x80) != 0 ) {
  579.         if ( (gctb = malloc((1 << pix) * 3)) == NULL ) {
  580.             free(wfp->wd_bftop); wfp->wd_bftop = NULL;
  581.             return;
  582.         }
  583.         fread(gctb,3,1 << pix,fp);
  584.     }
  585.  
  586. NEXTDISP:
  587.     fread(tmp,1,1,fp);
  588.     if ( tmp[0] != ',' )
  589.         goto ERROR;
  590.     fread(&dx,2,1,fp);
  591.     fread(&dy,2,1,fp);
  592.     fread(&mx,2,1,fp);
  593.     fread(&my,2,1,fp);
  594.     fread(tmp,1,1,fp);
  595.     if ( (tmp[0] & 0x80) != 0 )
  596.         fread(gctb,3,1 << pix,fp);
  597.  
  598.     if ( (sku = tmp[0] & 0x40) == 0 ) {
  599.         for ( y = 0 ; y < my ; y++ ) {
  600.             p = wfp->wd_bftop + (dx / 2) + (ex / 2) * (dy + y);
  601.             for ( x = 0 ; x < mx ; x++ ) {
  602.                 if ( (i = GIF_pix(pix,gcf,gctb,fp)) == EOF )
  603.                     goto ERROR;
  604.                 if ( (x & 1) == 0 ) { *p &= 0xf0; *p |= i; }
  605.                 else { *p &= 0x0f; *(p++) |= (i << 4); }
  606.             }
  607.             if ( (y & 15) == 15 ) {
  608.                 if ( y > wfp->wd_my ) wfp->wd_cy = y - wfp->wd_my;
  609.                 TIF_disp(wfp);
  610.             }
  611.         }
  612.     } else {
  613.         for ( j = 0 ; j < 4 ; j++ ) {
  614.             n = skutb[j];
  615.             for ( y = skusp[j] ; y < my ; y += n ) {
  616.                 p = wfp->wd_bftop + (dx / 2) + (ex / 2) * (dy + y);
  617.                 for ( x = 0 ; x < mx ; x++ ) {
  618.                     if ( (i = GIF_pix(pix,gcf,gctb,fp)) == EOF )
  619.                         goto ERROR;
  620.                     if ( (x & 1) == 0 ) { *p &= 0xf0; *p |= i; }
  621.                     else { *p &= 0x0f; *(p++) |= (i << 4); }
  622.                 }
  623.             }
  624.             TIF_disp(wfp);
  625.         }
  626.     }
  627.     dmy_close();
  628.     goto NEXTDISP;
  629.  
  630. ERROR:
  631.     if ( gcf != 0 ) free(gctb);
  632.     dmy_close();
  633.     return;
  634. }
  635. WINDFP  *GRA_open(char *file,int lx,int ly,int rx,int ry,int fra,int bak)
  636. {
  637.     int        md;
  638.     register WINDFP    *wfp;
  639.     FILE    *fp;
  640.     char    *sub;
  641.  
  642.     sub = subname(file) + 9;
  643.     if ( strcmp(sub,"TIF") == 0 )     md = 0;
  644.     else if ( strcmp(sub,"PIC") == 0 ) md = 1;
  645.     else if ( strcmp(sub,"GED") == 0 ) md = 2;
  646.     else if ( strcmp(sub,"FIG") == 0 ) md = 3;
  647.     else if ( strcmp(sub,"P16") == 0 ) md = 4;
  648.     else if ( strcmp(sub,"P25") == 0 ) md = 5;
  649.     else if ( strcmp(sub,"P32") == 0 ) md = 6;
  650.     else if ( strcmp(sub,"GRP") == 0 ) md = 7;
  651.     else if ( strcmp(sub,"GIF") == 0 ) md = 8;
  652.     else return NULL;
  653.  
  654.     lx &= 0xfffe; rx &= 0xfffe;
  655.     if ( (fp = fopen(file,"rb")) == NULL )
  656.         return NULL;
  657.     if ( (wfp = WIN_dmyopen(lx,ly,rx,ry)) == NULL ) {
  658.         fclose(fp);
  659.         return NULL;
  660.     }
  661.     fbox(lx,ly,rx,ry,fra,bak,0);
  662.     wfp->wd_entsiz = 0;
  663.     wfp->wd_mode = 0x0003;
  664.     wfp->wd_fra = wfp->wd_chr = fra; wfp->wd_bak = bak;
  665.     wfp->wd_dx = lx + 4; wfp->wd_dy = ly + 24;
  666.     wfp->wd_mx = (rx - 22) - (lx + 4); wfp->wd_my = (ry - 20) - (ly + 24);
  667.     wfp->wd_cx = wfp->wd_cy = 0;
  668.     wfp->wd_bftop = NULL;
  669.     wfp->wd_x = wfp->wd_y = wfp->wd_len = wfp->wd_tab = 0;
  670.     strcpy(wfp->wd_ttl,file);
  671.     WIN_display(wfp);
  672.  
  673.     switch(md) {
  674.         case 0: TIF_open(wfp,fp); break;
  675.         case 1: PIC_open(wfp,fp); break;
  676.         case 2: GED_open(wfp,fp); break;
  677.         case 3: FIG_open(wfp,fp); break;
  678.         case 4: P16_open(wfp,fp); break;
  679.         case 5: P25_open(wfp,fp); break;
  680.         case 6: P32_open(wfp,fp); break;
  681.         case 7: GRP_open(wfp,fp); break;
  682.         case 8: GIF_open(wfp,fp); break;
  683.     }
  684.     if ( wfp->wd_len == 0 )
  685.         goto ERROR;
  686.  
  687.     switch(wfp->wd_len) {
  688.         case 1: TIF_get1(wfp,fp); break;
  689.         case 4: TIF_get4(wfp,fp); break;
  690.         case 8: TIF_get8(wfp,fp); break;
  691.         case 16: TIF_get16(wfp,fp); break;
  692.     }
  693.     if ( wfp->wd_len >= 100 )
  694.         wfp->wd_len -= 100;
  695.  
  696.     if ( wfp->wd_bftop == NULL )
  697.         goto ERROR;
  698.  
  699.     wfp->wd_mode = 0x0003;
  700.     TIF_disp(wfp);
  701.     fclose(fp);
  702.     return wfp;
  703. ERROR:
  704.     WIN_close(wfp);
  705.     fclose(fp);
  706.     return NULL;
  707. }
  708.